home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / archiver / compress.zoo / compusi.c < prev    next >
C/C++ Source or Header  |  1989-06-30  |  9KB  |  308 lines

  1. /*@H************************ < COMPRESS utility> ****************************
  2. *                                                                           *
  3. *   compress : compusi.uni <Unix/Xenix support functions>                   *
  4. *                                                                           *
  5. *   port by  : Donald J. Gloistein                                          *
  6. *                                                                           *
  7. *   Source, Documentation, Object Code:                                     *
  8. *   released to Public Domain. This code is ported from compress v4.0       *
  9. *   release joe.                                                            *
  10. *                                                                           *
  11. *---------------------------  Module Description  --------------------------*
  12. *   Unix system dependent routines. These are specific to either the        *
  13. *   unix file structure or some unix only functions.                        *
  14. *                                                                           *
  15. *   Separated out for ease of writing the main module.                      *
  16. *                                                                           *
  17. *--------------------------- Implementation Notes --------------------------*
  18. *                                                                           *
  19. *   compiled with : compress.h compress.fns                                 *
  20. *   linked with   : compress.o compapi.o                                    *
  21. *                                                                           *
  22. *   To use, copy or rename this file to compusi.c and recompile.            *
  23. *   Set the defines in compress.h to reflect the status of your compiler's  *
  24. *   runtime library, allocation type for malloc()'s, and memory models if   *
  25. *   applicable, and your library function call for malloc() and free().     *
  26. *                                                                           *
  27. *   problems: header has some hardcoded defines you may need to change      *
  28. *             for your compiler. Please read the header thoroughly.         *
  29. *                                                                           *
  30. *                                        *
  31. *   Revision ++jrb                                *
  32. *    - replaced all '/' with separator[0]                    *
  33. *    - name mapping when MSDOS is defined                    *
  34. *       (ie filesystems with no multiple extensions)                *
  35. *       On compression                            *
  36. *        foo    -->    foo.Z                        *
  37. *        foo.c   -->    foo.cZ                        *
  38. *        foo.cc  -->    foo.ccZ                        *
  39. *        foo.ccc -->    foo.ccZ    notice the ambiguity            *
  40. *       On Uncompression                            *
  41. *        foo.Z    -->    foo                        *
  42. *        foo.cZ    -->    foo.c                        *
  43. *        foo.ccZ    -->    foo.cc                        *
  44. *        uncompress foo.cc with uncompress foo.ccZ            *
  45. *                                        *
  46. *---------------------------      Author(s)        -------------------------*
  47. *     Initials ---- Name ---------------------------------                  *
  48. *      DjG          Donald J. Gloistein                                     *
  49. *                   Plus many others, see rev.hst file for full list        *
  50. *      LvR          Lyle V. Rains, thanks for the improved implementation   *
  51. *                   of the compression and decompression routines.          *
  52. *************************************************************************@H*/
  53.  
  54. #include <stdio.h>
  55.  
  56. #include "compress.h" /* contains the rest of the include file declarations */
  57.  
  58. /* For those who don't have it in libc.a */
  59.  
  60. #ifdef NO_STRRCHR
  61. char  *strrchr(s,c)
  62. char *s;
  63. int c;
  64. {
  65.     register int count;
  66.  
  67.     while (*s){
  68.         s++;
  69.         count++;
  70.     }
  71.     s--;
  72.     while (count--)
  73.         if (*s == (char)c)
  74.             return(s);
  75.         else
  76.             s--;
  77.     return(NULL);
  78. }
  79. #endif
  80.  
  81. char *get_program_name(ptr)
  82. char *ptr;
  83. {
  84.     char *cp;
  85.     if ((cp = strrchr(ptr, separator[0])) != NULL)
  86.         cp++;
  87.     else
  88.         cp = ptr;
  89.  
  90. #ifdef MSDOS
  91.     if(strcmp(cp,"uncompre") == 0) {
  92. #else
  93.     if(strcmp(cp,"uncompress") == 0) {
  94. #endif
  95.         do_decomp = 1;
  96.     }
  97.     else
  98.     if(strcmp(cp, "zcat") == 0) {
  99.         keep = TRUE;
  100.         zcat_flg = do_decomp = 1;
  101.     }
  102.     return (cp);
  103. }
  104.  
  105.  
  106. char *name_index(ptr)
  107. char *ptr;
  108. {
  109.     char *p;
  110.  
  111.     p = strrchr(ptr,separator[0]);
  112.     return ((p)? ++p: ptr);
  113. }
  114.  
  115. int is_z_name(ptr)       /* checks if it is already a z name */
  116. char *ptr;
  117. {
  118. #ifndef MSDOS
  119.     return (!(strcmp(ptr + strlen(ptr) -2,".Z")));
  120. #else
  121.     extern char *rindex();
  122.     register int n;
  123.     register char *ext = rindex(ptr, '.');
  124.     
  125.     if(ext == NULL)
  126.     return 0;
  127.     n = strlen(ext) - 2;
  128.     return ((ext[n] == 'Z') || (ext[n] == 'z'));
  129. #endif
  130. }
  131.  
  132. int make_z_name(ptr)
  133. char *ptr;
  134. {
  135. #ifndef BSD4_2
  136. #ifndef MSDOS
  137.     if (strlen(name_index(ptr)) > 12 ) {
  138.         fprintf(stderr,"%s: filename too long to add .Z\n",name_index(ptr));
  139.         return FALSE;
  140.     }
  141. #else
  142.     extern char *rindex();
  143.     register int n;
  144.     register char *ext = rindex(ptr, '.');
  145.  
  146.     if(ext == NULL)
  147.     {
  148.     strcat(ptr, ".Z");
  149.     return TRUE;
  150.     }
  151.     if((n = strlen(ext)) < 4)
  152.     {
  153.     ext[n] = 'Z';
  154.     ext[n+1] = '\0';
  155.     }
  156.     else
  157.     ext[n-1] = 'Z';
  158.     return TRUE;
  159. #endif
  160. #endif
  161.     strcat(ptr,".Z");
  162.     return TRUE;
  163. }
  164. void unmake_z_name(ptr)
  165. char *ptr;
  166. {
  167. #ifdef MSDOS
  168.     extern char *rindex();
  169.     register char *ext = rindex(ptr, 'Z');
  170.  
  171.     if(ext == NULL)
  172.     ext = rindex(ptr, 'z');
  173.     
  174.     if(ext[-1] == '.')
  175.     {
  176.     ext[-1] = '\0';
  177.     return;
  178.     }
  179.     *ext = '\0';
  180.     return;
  181. #else
  182.     register int len = strlen(ptr)-2;
  183.  
  184.     ptr[len] = '\0';
  185. #endif
  186. }
  187.  
  188. #ifndef NOSIGNAL
  189. SIGTYPE onintr ( )
  190. {
  191.     if (!zcat_flg && !keep_error){
  192.         fclose(stdout);
  193.         unlink ( ofname );
  194.     }
  195.     exit ( ERROR );
  196. }
  197.  
  198. SIGTYPE oops ( )    /* wild pointer -- assume bad input */
  199. {
  200.     if ( do_decomp == 1 )
  201.         fprintf ( stderr, "%s: corrupt input: %s\n",prog_name,ifname);
  202.     if (!zcat_flg && !keep_error){
  203.         fclose(stdout);
  204.         unlink ( ofname );
  205.     }
  206.     exit ( ERROR );
  207. }
  208. #endif
  209.  
  210. void copystat(ifname, ofname)
  211. char *ifname, *ofname;
  212. {
  213.     struct stat statbuf;
  214.     int mode;
  215.     time_t timep[2];
  216.  
  217.     fclose(stdout);
  218.     if (stat(ifname, &statbuf)) {       /* Get stat on input file */
  219.         perror(ifname);
  220.         return;
  221.     }
  222.     if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) {
  223.         if(quiet)
  224.             fprintf(stderr, "%s: ", ifname);
  225.         fprintf(stderr, " -- not a regular file: unchanged");
  226.         exit_stat = 1;
  227.     }
  228.     else if (statbuf.st_nlink > 1) {
  229.         if(quiet)
  230.             fprintf(stderr, "%s: ", ifname);
  231.         fprintf(stderr, " -- has %d other links: unchanged",
  232.             statbuf.st_nlink - 1);
  233.         exit_stat = ERROR;
  234.     }
  235.     else if (exit_stat == NOSAVING && (!force)) { /* No compression: remove file.Z */
  236.     if(!quiet)
  237.         fprintf(stderr, " -- no savings -- file unchanged");
  238.     }
  239.     else if (exit_stat == NOMEM){
  240.         if (!quiet)
  241.             fprintf(stderr, " -- file unchanged");
  242.         if (!do_decomp)
  243.             exit(ERROR);
  244.         else
  245.             return;     /* otherwise will unlink outfile */
  246.     }
  247.     else if (exit_stat == OK) {  /* ***** Successful Compression ***** */
  248.         mode = statbuf.st_mode & 07777;
  249.         if (chmod(ofname, mode))        /* Copy modes */
  250.                 perror(ofname);
  251.         chown(ofname,statbuf.st_uid,statbuf.st_gid); /* Copy Ownership */
  252.         timep[0] = statbuf.st_atime;
  253.         timep[1] = statbuf.st_mtime;
  254.         utime(ofname,timep);   /* Update last accessed and modified times */
  255.         if (!keep){
  256.             fclose(stdin);
  257.             if (unlink(ifname)) /* Remove input file */
  258.                 perror(ifname);
  259.             if(!quiet)
  260.                 fprintf(stderr, " -- replaced with %s", ofname);
  261.         }
  262.         else{
  263.             if(!quiet)
  264.                 fprintf(stderr, " -- compressed to %s", ofname);
  265.         }
  266.         return;     /* Successful return */
  267.     }
  268.  
  269.     /* Unsuccessful return -- one of the tests failed */
  270.     fclose(stdout);
  271.     if (unlink(ofname))
  272.         perror(ofname);
  273. }
  274. void version()
  275. {
  276. #ifdef XENIX
  277. #ifndef NDEBUG
  278.     fprintf(stderr, "%s\nOptions: Xenix %s MAXBITS = %d\n", rcs_ident,
  279.         "DEBUG",MAXBITS);
  280. #else
  281.     fp